package com.pi.shisan.test.client.start;

import com.pi.shisan.component.impl.LocalDateComponent;
import com.pi.shisan.component.impl.LocalTimeComponent;
import com.pi.shisan.test.client.util.DefaultFont8x8;
import com.pi.shisan.test.client.util.FackGpio;
import com.pi.shisan.util.spipoint.MergedSpi;
import com.pi.shisan.util.spipoint.MultipleFlushSpi;
import com.pi.shisan.util.spipoint.MultipleXyToSpiConverter;
import io.netty.channel.Channel;

import static com.pi.shisan.test.client.util.FackGpio.channel;
import static com.pi.shisan.test.client.util.FackGpio.digitalWrite;

public class StartListener {

    long[] all = {DefaultFont8x8.UPPER_A, DefaultFont8x8.UPPER_B, DefaultFont8x8.UPPER_C, DefaultFont8x8.UPPER_D, DefaultFont8x8.UPPER_E, DefaultFont8x8.UPPER_F, DefaultFont8x8.UPPER_G,
            DefaultFont8x8.UPPER_H, DefaultFont8x8.UPPER_I, DefaultFont8x8.UPPER_J, DefaultFont8x8.UPPER_K, DefaultFont8x8.UPPER_L, DefaultFont8x8.UPPER_M, DefaultFont8x8.UPPER_N,
            DefaultFont8x8.UPPER_O, DefaultFont8x8.UPPER_P, DefaultFont8x8.UPPER_Q, DefaultFont8x8.UPPER_R, DefaultFont8x8.UPPER_S, DefaultFont8x8.UPPER_T,
            DefaultFont8x8.UPPER_U, DefaultFont8x8.UPPER_V, DefaultFont8x8.UPPER_W, DefaultFont8x8.UPPER_X, DefaultFont8x8.UPPER_Y, DefaultFont8x8.UPPER_Z,
            DefaultFont8x8.SIGN_FALSE, DefaultFont8x8.SIGN_EMBARRASS, DefaultFont8x8.SIGN_TRUE, DefaultFont8x8.SIGN_PAND,
            DefaultFont8x8.SIGN_UNKONW, DefaultFont8x8.SIGN_WARN, DefaultFont8x8.FACE_HAPPY, DefaultFont8x8.FACE_NORMAL, DefaultFont8x8.FACE_SHRPRISE, DefaultFont8x8.FACE_UNHAPPY,
            DefaultFont8x8.SIGN_LOVE, DefaultFont8x8.SIGN_LOVE_FILL, DefaultFont8x8.NUM_5_LEFT, DefaultFont8x8.NUM_6_RIGHT,
            DefaultFont8x8.SIGN_LOADING, DefaultFont8x8.SIGN_LOADING_FILL,
            DefaultFont8x8.GIF_CIRCLE_LOADING[0],
            DefaultFont8x8.GIF_CIRCLE_LOADING[1],
            DefaultFont8x8.GIF_CIRCLE_LOADING[2],
            DefaultFont8x8.GIF_CIRCLE_LOADING[3],
            DefaultFont8x8.GIF_CIRCLE_LOADING[4],
            DefaultFont8x8.GIF_CIRCLE_LOADING[5],
            DefaultFont8x8.GIF_CIRCLE_LOADING[6],
            DefaultFont8x8.GIF_CIRCLE_LOADING[7],
            DefaultFont8x8.GIF_CIRCLE_LOADING[8],
            DefaultFont8x8.GIF_CIRCLE_LOADING[9],
            DefaultFont8x8.GIF_CIRCLE_LOADING[10],
            DefaultFont8x8.GIF_CIRCLE_LOADING[11],
            DefaultFont8x8.GIF_CIRCLE_LOADING[12],
            DefaultFont8x8.GIF_CIRCLE_LOADING[13],
            DefaultFont8x8.GIF_CIRCLE_LOADING[14],
            DefaultFont8x8.GIF_LINE_LOADING[0],
            DefaultFont8x8.GIF_LINE_LOADING[1],
            DefaultFont8x8.GIF_LINE_LOADING[2],
            DefaultFont8x8.GIF_LINE_LOADING[3],
            DefaultFont8x8.GIF_LINE_LOADING[4],
            DefaultFont8x8.GIF_LINE_LOADING[5],
            DefaultFont8x8.NUM_ZERO,
            DefaultFont8x8.NUM_ONE,
            DefaultFont8x8.NUM_TWO,
            DefaultFont8x8.NUM_THREE,
            DefaultFont8x8.NUM_FOUR,
            DefaultFont8x8.NUM_FIVE,
            DefaultFont8x8.NUM_SIX,
            DefaultFont8x8.NUM_SEVEN,
            DefaultFont8x8.NUM_EIGHT,
            DefaultFont8x8.NUM_NINE,
            -1
    };

    private final static int LOW = 0, HIGH = 1, OUTPUT = 1, INPUT = 0;

    public StartListener(Channel channel) {
        FackGpio.setByteBuf(channel);
    }

    public void run() {

//        wiringPiSetup();
//        pinMode(DIN,OUTPUT);
//        pinMode(CS,OUTPUT);
//        pinMode(CLK,OUTPUT);
//        digitalWrite(CS, LOW);
//        writeData(0x09,0x00);
//        writeData(0x09,0x00);
//        writeData(0x09,0x00);
//        writeData(0x09,0x00);
//        digitalWrite(CS, HIGH);
//        digitalWrite(CLK,HIGH);
//        digitalWrite(CS, LOW);
//        writeData(0x0a,0x03);
//        writeData(0x0a,0x03);
//        writeData(0x0a,0x03);
//        writeData(0x0a,0x03);
//        writeData(0x0a,0x03);
//        digitalWrite(CS, HIGH);
//        digitalWrite(CLK,HIGH);
//        digitalWrite(CS, LOW);
//        writeData(0x0b,0x07);
//        writeData(0x0b,0x07);
//        writeData(0x0b,0x07);
//        writeData(0x0b,0x07);
//        writeData(0x0b,0x07);
//        digitalWrite(CS, HIGH);
//        digitalWrite(CLK,HIGH);
//        digitalWrite(CS, LOW);
//        writeData(0x0c,0x01);
//        writeData(0x0c,0x01);
//        writeData(0x0c,0x01);
//        writeData(0x0c,0x01);
//        writeData(0x0c,0x01);
//        32 x 24
//        17 x 5
//        000 000   000 000
//        0 0 0 0 0 0 0 0 0
//        000 000   000 000
//        0 0 0 0 0 0 0 0 0
//        000 000   000 000
//
//        digitalWrite(CS, HIGH);
//        digitalWrite(CLK,HIGH);
//        digitalWrite(CS, LOW);
//        writeData(0xff,0x00);
//        writeData(0xff,0x00);
//        writeData(0xff,0x00);
//        writeData(0xff,0x00);
//        writeData(0xff,0x00);
//        digitalWrite(CS, HIGH);
//        digitalWrite(CLK,HIGH);
//        writeData(1,12);
//        writeData(1,12);
//        writeData(1,12);
//        writeData(1,12);
//        writeData(1,12);
//        writeData(1,12);
//        writeData(1,12);
//        writeData(1,12);

//        int index = 0;
//        byte[][] data = new byte[4][8];
//        while (true) {
//            for (int i = 0; i < 4; i++) {
//                if (index >= all.length) {
//                    index = 0;
//                }
//                data[i] = DefaultFont8x8.getPoints(all[index]);
//                index ++;
//            }
//            for (int j = 1; j <= 8; j++) {
//                digitalWrite(CS, LOW);
//                for (int i = 0; i < 4; i++) {
//                    writeData(j, data[i][j-1]);
////                    digitalWrite(CLK,HIGH);
//                }
////                digitalWrite(CLK,HIGH);
//                digitalWrite(CS, HIGH);
//            }
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//            }
//        }

//        int index = 0;
//        while (true) {
//            if (index >= all.length) {
//                index = 0;
//            }
//            byte[] data = DefaultFont8x8.getPoints(all[index++]);
//            for (int i = 0; i < data.length; i++) {
//                writeData(i+1, data[i]);
//                digitalWrite(CLK,HIGH);
//                writeData(i+1, data[i]);
//                digitalWrite(CLK,HIGH);
//                writeData(i+1, data[i]);
//                digitalWrite(CLK,HIGH);
//                writeData(i+1, data[i]);
//            }
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }


//        int size = 12;
//        int index = 0;
//        int tmpIndex = 0;
//        long point;
//        int y;
//        while (true) {
//            index = tmpIndex;
//            channel.write((short)5);
//            channel.write((short)(8 * size));
//            for (int i = 0; i < size; i++) {
//                if (index >= all.length) {
//                    index = 0;
//                }
//                point = all[index];
//                point = (i / 4 & 1) == 0 ? point : rotate180(point);
//                if (i == size - 1) {
//                    channel.writeAndFlush(point);
//                } else {
//                    channel.write(point);
//                }
//                index++;
//                if (i == 0) {
//                    tmpIndex = index;
//                }
//            }
//            try {
//                Thread.sleep(500);
//            } catch (InterruptedException e) {
//            }
//        }


//        String text = "十三爱娇娇";
//        int[] allPoints = TextPxCreater.getAllPointsSameLine(text, 16);
//        int startX = 31;
//        while (true) {
//            MergedSpi spi = new MergedSpi(4,3, 1);
//            for (int point : allPoints) {
//                spi.put((point >> 16) + startX, (point & 0xFFFF) + 5);
//            }
//            long[] points = spi.toSpiPoints();
////            System.out.println(spi.toString());
//            channel.write((short)5);
//            channel.write((short)(8 * points.length));
//            for (int i = 0; i < points.length; i++) {
//                if (i < points.length - 1) {
//                    channel.write(points[i]);
//                } else {
//                    channel.writeAndFlush(points[i]);
//                }
//            }
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            startX--;
//            if (startX < -75) {
//                startX = 31;
//            }
//        }

//        MergedSpi spi = new MergedSpi(4,3);
//        spi.put(0,8);
//        long[] points = spi.toSpiPoints();
//        System.out.println(spi.toString());
//        channel.write((short)5);
//        channel.write((short)(8 * points.length));
//        for (int i = 0; i < points.length; i++) {
//            if (i < points.length - 1) {
//                channel.write(points[i]);
//            } else {
//                channel.writeAndFlush(points[i]);
//            }
//        }


//        while (true) {
//            channel.write((short)5);
//            channel.write((short)(12*8));
//            for (int i = 0; i < 12; i++) {
//                if (i < 11) {
//                    channel.write(all[i]);
//                } else {
//                    channel.writeAndFlush(all[i]);
//                }
//            }
//            try {
//                Thread.sleep(2000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }

//        channel.write((short)7);
//        channel.write((short)0);


        MultipleFlushSpiNetty spi = new MultipleFlushSpiNetty(new MergedSpi(4, 3, true), channel);
        LocalDateComponent component = new LocalDateComponent(spi,spi);
        component.setY(16);
        component.setH(8);
        component.start();
//
        LocalTimeComponent component1 = new LocalTimeComponent(spi,spi);
        component1.setY(5);
        component1.setX(1);
        component1.setW(30);
        component1.start();

        new Thread(() -> {
//            ProcessStateComponent component = new ProcessStateComponent(spi,spi);
//            component.setY(22);
//            component.setW(26);
//            component.setX(3);
//            component.show();
//            for (int i = 90; i <= 100; i++) {
//                component.setVal(i);
//                try {
//                    Thread.sleep(1000);
//                } catch (InterruptedException e) {
//                }
//            }

//            MusicEffectComponent component = new MusicEffectComponent(spi, spi);
//            component.setH(24);
//            component.setW(2);
//            component.show();
//
//            MusicEffectComponent component2 = new MusicEffectComponent(spi, spi);
//            component2.setH(24);
//            component2.setW(2);
//            component2.setX(30);
//            component2.show();
////
//            while (true) {
//                component.setVal(new Random().nextInt(25));
//                component2.setVal(new Random().nextInt(25));
//                try {
//                    Thread.sleep(500);
//                } catch (InterruptedException e) {
//                }
//            }
        })/*.start()*/;
    }


    private static final int CS = 11, CLK = 14, DIN = 12;
    private static final byte[] NONE_POINT = new byte[]{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};

    //写入一个8x8片前CS=0,写完后CS=1；同时如果是第二个，需要写空

    private void writeData(int addr, int data) {
//        digitalWrite(CS, LOW);
        writeByte(addr);
        writeByte(data);
//        digitalWrite(CS, HIGH);
        digitalWrite(CLK, HIGH);
    }

    private void writeByte(int data) {
        for (int i = 0; i < 8; i++) {
            digitalWrite(CLK, LOW);
            digitalWrite(DIN, (data & 0x80) == 0 ? LOW : HIGH);
            digitalWrite(CLK, HIGH);
            data <<= 1;
        }
    }

    public static class MultipleFlushSpiNetty extends MultipleFlushSpi {

        private Channel channel;

        private MultipleFlushSpiNetty(MultipleXyToSpiConverter multipleXyToSpiConverter) {
            super(multipleXyToSpiConverter);
        }

        public MultipleFlushSpiNetty(MultipleXyToSpiConverter multipleXyToSpiConverter, Channel channel) {
            super(multipleXyToSpiConverter);
            this.channel = channel;
        }

        @Override
        public void flushData() {
//            simpleThread.execute(() -> {
            long[] points = super.toSpiPoints();
                channel.write((short) 5);
                channel.write((short) (points.length * 8));
                for (int i = 0; i < points.length; i++) {
                    if (i == points.length - 1) {
                        channel.writeAndFlush(points[i]);
                    } else {
                        channel.write(points[i]);
                    }
                }
//            });
        }
    }
}
